#!/bin/bash

# Test script for cjgit.sh and cjbuild.sh workflow
# Set bash to print every command
set -x

# Function to abort on failure
abort_on_failure() {
    if [ $? -ne 0 ]; then
        echo "STEP FAILED: $1"
        echo "Root directory: $TEMP_ROOT"
        echo "Aborting test script"
        exit 1
    fi
}

# Step 1: Create a temp directory and step into it, remember it as root, perform cjgit.sh and cjgit.sh help
echo "=== Step 1: Creating temp directory and testing help ==="
TEMP_ROOT=$(mktemp -d)
cd "$TEMP_ROOT"
abort_on_failure "Failed to create temp directory"

# Make sure cjgit.sh is available from the original location
export PATH="/home/m00816528/projects/snippets:$PATH"

cjgit.sh
abort_on_failure "cjgit.sh failed"

cjgit.sh help
abort_on_failure "cjgit.sh help failed"

# Step 2: cjgit.sh clone
echo "=== Step 2: Cloning projects ==="
cjgit.sh clone
abort_on_failure "cjgit.sh clone failed"

# Step 3: List directories and check that all subprojects are present, step into every and perform git status, return back to the root
echo "=== Step 3: Checking subprojects and git status ==="
ls -la
abort_on_failure "Failed to list directories"

expected_projects=("cangjie_compiler" "cangjie_runtime" "cangjie_stdx" "cangjie_tools" "cangjie_multiplatform_interop" "cangjie_docs")

for project in "${expected_projects[@]}"; do
    if [ ! -d "$project" ]; then
        echo "ERROR: Project $project not found"
        exit 1
    fi
    cd "$project"
    git status
    abort_on_failure "git status failed for $project"
    cd ..
done

# Step 4: cjgit.sh status
echo "=== Step 4: Checking cjgit status ==="
cjgit.sh status
abort_on_failure "cjgit.sh status failed"

# Step 5: cjgit.sh clone (second time)
echo "=== Step 5: Second clone operation ==="
cjgit.sh clone
abort_on_failure "Second cjgit.sh clone failed"

# Step 6: Remove cangjie_docs
echo "=== Step 6: Removing cangjie_docs ==="
rm -rf cangjie_docs
abort_on_failure "Failed to remove cangjie_docs"

# Step 7: Step into cangjie_compiler
echo "=== Step 7: Stepping into cangjie_compiler ==="
cd cangjie_compiler
abort_on_failure "Failed to cd into cangjie_compiler"

# Step 8: cjgit.sh clone
echo "=== Step 8: Clone from cangjie_compiler directory ==="
cjgit.sh clone
abort_on_failure "cjgit.sh clone failed from cangjie_compiler"

# Step 9: cd back to the root
echo "=== Step 9: Return to root ==="
cd "$TEMP_ROOT"
abort_on_failure "Failed to return to root directory"

# Step 10: check that cangjie_docs is back again and it's a git repo
echo "=== Step 10: Checking cangjie_docs is restored ==="
if [ ! -d "cangjie_docs" ]; then
    echo "ERROR: cangjie_docs not restored"
    exit 1
fi

cd cangjie_docs
if [ ! -d ".git" ]; then
    echo "ERROR: cangjie_docs is not a git repository"
    exit 1
fi
cd ..

# Step 11: Check every sub-project
echo "=== Step 11: Comprehensive sub-project checks ==="
for project in "${expected_projects[@]}"; do
    echo "Checking project: $project"
    cd "$project"
    
    # Check it's a git repo
    if [ ! -d ".git" ]; then
        echo "ERROR: $project is not a git repository"
        exit 1
    fi
    
    # git status
    git status
    abort_on_failure "git status failed for $project"
    
    # Check the branch is "dev"
    current_branch=$(git branch --show-current)
    if [ "$current_branch" != "dev" ]; then
        echo "ERROR: $project branch is '$current_branch', expected 'dev'"
        exit 1
    fi
    
    # git remote returns two remotes: upstream and myfork (order doesn't matter)
    remotes=$(git remote)
    remote_count=$(echo "$remotes" | wc -l)
    if [ "$remote_count" != "2" ]; then
        echo "ERROR: $project has $remote_count remotes, expected 2"
        echo "Remotes found: $remotes"
        exit 1
    fi
    
    # Check that both required remotes exist (order doesn't matter)
    if ! echo "$remotes" | grep -q "upstream"; then
        echo "ERROR: $project missing 'upstream' remote"
        echo "Remotes found: $remotes"
        exit 1
    fi
    
    if ! echo "$remotes" | grep -q "myfork"; then
        echo "ERROR: $project missing 'myfork' remote"
        echo "Remotes found: $remotes"
        exit 1
    fi
    
    # git pull
    git pull
    abort_on_failure "git pull failed for $project"
    
    # git push -f myfork
    git push -f myfork
    abort_on_failure "git push -f myfork failed for $project"
    
    cd ..
done

# Step 12: back to the root (already there)
echo "=== Step 12: Already at root ==="

# Step 13: cjgit.sh new test<random>
echo "=== Step 13: Creating new branch with random name ==="
RANDOM_SUFFIX=$(shuf -i 1000-9999 -n 1)
BRANCH_NAME="test$RANDOM_SUFFIX"
cjgit.sh new "$BRANCH_NAME"
abort_on_failure "cjgit.sh new $BRANCH_NAME failed"

# Step 14: Check every subproject and the branch should be the random branch name
echo "=== Step 14: Verifying all projects are on $BRANCH_NAME branch ==="
for project in "${expected_projects[@]}"; do
    cd "$project"
    current_branch=$(git branch --show-current)
    if [ "$current_branch" != "$BRANCH_NAME" ]; then
        echo "ERROR: $project branch is '$current_branch', expected '$BRANCH_NAME'"
        exit 1
    fi
    cd ..
done

# Step 15: cjgit.sh push
echo "=== Step 15: Pushing to $BRANCH_NAME branch ==="
cjgit.sh push
abort_on_failure "cjgit.sh push failed"



# Step 16: cjgit.sh status
echo "=== Step 16: Checking status ==="
cjgit.sh status
abort_on_failure "cjgit.sh status failed"

# Step 17: cd cangjie_compiler && echo 1 > 1 && git add 1 && git commit -s -m "fix: aaa" && cd ..
echo "=== Step 17: Making changes in cangjie_compiler ==="
cd cangjie_compiler
echo 1 > 1
git add 1
git commit -s -m "fix: aaa"
abort_on_failure "Failed to commit changes in cangjie_compiler"
cd ..

# Step 18: cjgit.sh status | grep cangjie_compiler | grep [push] shouldn't be empty
echo "=== Step 18: Checking for push status on cangjie_compiler ==="
push_status=$(cjgit.sh status | grep cangjie_compiler | grep '\[push\]')
if [ -z "$push_status" ]; then
    echo "ERROR: cangjie_compiler should show [push] status"
    exit 1
fi

# Step 19: cjgit.sh push
echo "=== Step 19: Pushing changes ==="
cjgit.sh push
abort_on_failure "cjgit.sh push failed"

# Step 20: cjgit.sh status | grep cangjie_compiler | grep [push] should be empty
echo "=== Step 20: Verifying push status is cleared ==="
push_status=$(cjgit.sh status | grep cangjie_compiler | grep '\[push\]')
if [ -n "$push_status" ]; then
    echo "ERROR: cangjie_compiler should not show [push] status after push"
    exit 1
fi

# Step 21: cjgit.sh pull
echo "=== Step 21: Pulling latest changes ==="
cjgit.sh pull
abort_on_failure "cjgit.sh pull failed"

# Step 22: cd cangjie_runtime ; find some commit earlier, e.g. 10th from the HEAD and hard reset the branch to it then force push it, then cd to the root
echo "=== Step 22: Resetting cangjie_runtime to earlier commit ==="
cd cangjie_runtime
commit_to_reset=$(git log --oneline | head -n 10 | tail -n 1 | awk '{print $1}')
git reset --hard "$commit_to_reset"
abort_on_failure "Failed to reset cangjie_runtime"
git push -f
abort_on_failure "Failed to force push cangjie_runtime"
cd ..

# Step 23: cjgit.sh status | grep cangjie_runtime | grep [pull] should NOT be empty
echo "=== Step 23: Checking for pull status on cangjie_runtime ==="
pull_status=$(cjgit.sh status | grep cangjie_runtime | grep '\[pull\]')
if [ -z "$pull_status" ]; then
    echo "ERROR: cangjie_runtime should show [pull] status"
    exit 1
fi

# Step 24: cjgit.sh pull
echo "=== Step 24: Pulling changes for cangjie_runtime ==="
cjgit.sh pull
abort_on_failure "cjgit.sh pull failed"

# Step 25: cjgit.sh status | grep cangjie_runtime | grep [pull] should be empty
echo "=== Step 25: Verifying pull status is cleared ==="
pull_status=$(cjgit.sh status | grep cangjie_runtime | grep '\[pull\]')
if [ -n "$pull_status" ]; then
    echo "ERROR: cangjie_runtime should not show [pull] status after pull"
    exit 1
fi

# Step 26: Delete remote branch from all projects
echo "=== Step 26: Deleting remote branch $BRANCH_NAME from all projects ==="
for project in "${expected_projects[@]}"; do
    echo "Deleting remote branch from $project"
    cd "$project"
    git push -d myfork "$BRANCH_NAME"
    # Note: This might fail if branch doesn't exist on remote, which is acceptable
    if [ $? -ne 0 ]; then
        echo "WARNING: Failed to delete remote branch from $project (branch might not exist on remote)"
    fi
    cd ..
done

# Step 27: TARGET_ORG=mashser cjgit.sh pr "Test PR (WIP)"
echo "=== Step 27: Creating pull request ==="
TARGET_ORG=mashser cjgit.sh pr "Test PR (WIP)"
# Note: This might fail if PR already exists or if GitCode credentials are not set up
# We'll allow this step to fail gracefully
if [ $? -ne 0 ]; then
    echo "WARNING: PR creation failed (might be expected if PR exists or credentials missing)"
fi

# Step 28: Remove the root directory
echo "=== Step 28: Cleaning up temp directory ==="
cd /
rm -rf "$TEMP_ROOT"
abort_on_failure "Failed to remove temp directory"

echo "=== ALL TESTS PASSED ==="